Warning: mkdir(): No space left on device in /var/www/tg-me/post.php on line 37
Warning: file_put_contents(aCache/aDaily/post/golangtests/--): Failed to open stream: No such file or directory in /var/www/tg-me/post.php on line 50 Go tests | Telegram Webview: golangtests/764 -
👣Задача с подвохом, который связан с изменением поведения циклов, введенным в Go 1.22 (и, соответственно, актуальным для Go 1.24).
Задача: Что выведет следующий код при компиляции и запуске с использованием Go 1.24?
package main
import ( "fmt" "sync" "time" )
func main() { var wg sync.WaitGroup count := 3
fmt.Println("Запуск горутин...") wg.Add(count)
for i := 0; i < count; i++ { // Запускаем горутину в каждой итерации go func() { defer wg.Done() // Имитируем небольшую работу time.Sleep(time.Duration(10) * time.Millisecond) // Используем переменную цикла 'i' внутри горутины fmt.Printf("Горутина видит i = %d\n", i) }() }
fmt.Println("Ожидание завершения горутин...") wg.Wait() fmt.Println("Все горутины завершены.") }
Разбор: Классическая проблема (до Go 1.22): В версиях Go до 1.22 существовала известная проблема с захватом переменных цикла в замыканиях (функциях, создаваемых внутри цикла, как наша анонимная горутина). Переменная i была одна на весь цикл.
Когда горутины реально начинали выполняться (после небольшой задержки time.Sleep), цикл for, скорее всего, уже завершался. К этому моменту переменная i имела бы свое конечное значение (в данном случае 3, так как цикл завершается, когда i становится равным count).
Поэтому в старых версиях Go этот код, скорее всего, вывел бы: Запуск горутин... Ожидание завершения горутин... Горутина видит i = 3 Горутина видит i = 3 Горутина видит i = 3
Все горутины завершены.
(Порядок строк "Горутина видит..." мог быть разным). Чтобы обойти это, раньше приходилось делать так: i := i внутри цикла перед запуском горутины, чтобы создать копию переменной для каждой итерации.
Новое поведение (Go 1.22 и новее, включая 1.24): Начиная с Go 1.22, семантика переменных цикла for была изменена для предотвращения этой распространенной ошибки. Теперь переменная цикла (i в нашем случае) пересоздается для каждой итерации.
Это означает, что каждая горутина захватывает свою собственную копию i, соответствующую значению на момент этой итерации.
Ожидаемый вывод (Go 1.24): Благодаря изменению в Go 1.22, каждая горутина теперь корректно видит значение i той итерации, в которой она была запущена. Поэтому вывод будет (порядок строк "Горутина видит..." может варьироваться из-за недетерминированного планирования горутин): Запуск горутин... Ожидание завершения горутин... Горутина видит i = 0 Горутина видит i = 1 Горутина видит i = 2 Все горутины завершены. Use code with caution. Или, например: Запуск горутин... Ожидание завершения горутин... Горутина видит i = 2 Горутина видит i = 0 Горутина видит i = 1 Все горутины завершены.
Подвох заключается в том, что код выглядит как классический пример ошибки захвата переменной цикла, но из-за изменений в языке начиная с Go 1.22, он теперь работает "правильно" без необходимости явного копирования переменной (i := i).
👣Задача с подвохом, который связан с изменением поведения циклов, введенным в Go 1.22 (и, соответственно, актуальным для Go 1.24).
Задача: Что выведет следующий код при компиляции и запуске с использованием Go 1.24?
package main
import ( "fmt" "sync" "time" )
func main() { var wg sync.WaitGroup count := 3
fmt.Println("Запуск горутин...") wg.Add(count)
for i := 0; i < count; i++ { // Запускаем горутину в каждой итерации go func() { defer wg.Done() // Имитируем небольшую работу time.Sleep(time.Duration(10) * time.Millisecond) // Используем переменную цикла 'i' внутри горутины fmt.Printf("Горутина видит i = %d\n", i) }() }
fmt.Println("Ожидание завершения горутин...") wg.Wait() fmt.Println("Все горутины завершены.") }
Разбор: Классическая проблема (до Go 1.22): В версиях Go до 1.22 существовала известная проблема с захватом переменных цикла в замыканиях (функциях, создаваемых внутри цикла, как наша анонимная горутина). Переменная i была одна на весь цикл.
Когда горутины реально начинали выполняться (после небольшой задержки time.Sleep), цикл for, скорее всего, уже завершался. К этому моменту переменная i имела бы свое конечное значение (в данном случае 3, так как цикл завершается, когда i становится равным count).
Поэтому в старых версиях Go этот код, скорее всего, вывел бы: Запуск горутин... Ожидание завершения горутин... Горутина видит i = 3 Горутина видит i = 3 Горутина видит i = 3
Все горутины завершены.
(Порядок строк "Горутина видит..." мог быть разным). Чтобы обойти это, раньше приходилось делать так: i := i внутри цикла перед запуском горутины, чтобы создать копию переменной для каждой итерации.
Новое поведение (Go 1.22 и новее, включая 1.24): Начиная с Go 1.22, семантика переменных цикла for была изменена для предотвращения этой распространенной ошибки. Теперь переменная цикла (i в нашем случае) пересоздается для каждой итерации.
Это означает, что каждая горутина захватывает свою собственную копию i, соответствующую значению на момент этой итерации.
Ожидаемый вывод (Go 1.24): Благодаря изменению в Go 1.22, каждая горутина теперь корректно видит значение i той итерации, в которой она была запущена. Поэтому вывод будет (порядок строк "Горутина видит..." может варьироваться из-за недетерминированного планирования горутин): Запуск горутин... Ожидание завершения горутин... Горутина видит i = 0 Горутина видит i = 1 Горутина видит i = 2 Все горутины завершены. Use code with caution. Или, например: Запуск горутин... Ожидание завершения горутин... Горутина видит i = 2 Горутина видит i = 0 Горутина видит i = 1 Все горутины завершены.
Подвох заключается в том, что код выглядит как классический пример ошибки захвата переменной цикла, но из-за изменений в языке начиная с Go 1.22, он теперь работает "правильно" без необходимости явного копирования переменной (i := i).
BY Go tests
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Durov said on his Telegram channel today that the two and a half year blockchain and crypto project has been put to sleep. Ironically, after leaving Russia because the government wanted his encryption keys to his social media firm, Durov’s cryptocurrency idea lost steam because of a U.S. court. “The technology we created allowed for an open, free, decentralized exchange of value and ideas. TON had the potential to revolutionize how people store and transfer funds and information,” he wrote on his channel. “Unfortunately, a U.S. court stopped TON from happening.”
Export WhatsApp stickers to Telegram on Android
From the Files app, scroll down to Internal storage, and tap on WhatsApp. Once you’re there, go to Media and then WhatsApp Stickers. Don’t be surprised if you find a large number of files in that folder—it holds your personal collection of stickers and every one you’ve ever received. Even the bad ones.Tap the three dots in the top right corner of your screen to Select all. If you want to trim the fat and grab only the best of the best, this is the perfect time to do so: choose the ones you want to export by long-pressing one file to activate selection mode, and then tapping on the rest. Once you’re done, hit the Share button (that “less than”-like symbol at the top of your screen). If you have a big collection—more than 500 stickers, for example—it’s possible that nothing will happen when you tap the Share button. Be patient—your phone’s just struggling with a heavy load.On the menu that pops from the bottom of the screen, choose Telegram, and then select the chat named Saved messages. This is a chat only you can see, and it will serve as your sticker bank. Unlike WhatsApp, Telegram doesn’t store your favorite stickers in a quick-access reservoir right beside the typing field, but you’ll be able to snatch them out of your Saved messages chat and forward them to any of your Telegram contacts. This also means you won’t have a quick way to save incoming stickers like you did on WhatsApp, so you’ll have to forward them from one chat to the other.